Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Persistent array</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Persistent_array"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.math.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Persistent_array rootpage-Persistent_array skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Persistent array</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<p>In <a href="Computer_science" title="Computer science">computer science</a>, and more precisely regarding <a href="Data_structure" title="Data structure">data structures</a>, a <b>persistent array</b> is a <a href="Persistent_data_structure" title="Persistent data structure">persistent data structure</a> with properties similar to a (non-persistent) <a href="Array_data_structure" class="mw-redirect" title="Array data structure">array</a>. That is, after a value's update in a persistent array, there exist two persistent arrays: one persistent array in which the update is taken into account, and one which is equal to the array before the update.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Difference_between_persistent_arrays_and_arrays">Difference between persistent arrays and arrays</h2></div>
<p>An array
<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathrm {ar} =[e_{0},\dots ,e_{n-1}]}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="normal">a</mi>
<mi mathvariant="normal">r</mi>
</mrow>
<mo>=</mo>
<mo stretchy="false">[</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>n</mi>
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">]</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathrm {ar} =[e_{0},\dots ,e_{n-1}]}</annotation>
</semantics>
</math></span><img src="./11abefe5c589f71d62c967bf80ba9a173501a691.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:18.185ex; height:2.843ex;" alt="{\displaystyle \mathrm {ar} =[e_{0},\dots ,e_{n-1}]}" loading="lazy"></span> is a data structure,
with a fixed number <i>n</i> of elements <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle e_{0},\dots ,e_{n-1}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>n</mi>
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msub>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle e_{0},\dots ,e_{n-1}}</annotation>
</semantics>
</math></span><img src="./229df61e270f3f8c2a964a36c514f251cd9a6adc.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.671ex; width:11.718ex; height:2.009ex;" alt="{\displaystyle e_{0},\dots ,e_{n-1}}" loading="lazy"></span>. It is expected that, given the array <i>ar</i> and an
index <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 0\leq i<n}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mn>0</mn>
<mo>≤<!-- ≤ --></mo>
<mi>i</mi>
<mo>&lt;</mo>
<mi>n</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 0\leq i&lt;n}</annotation>
</semantics>
</math></span><img src="./3580bfd665087b84b88971bf567b87ab86b42871.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.505ex; width:9.557ex; height:2.343ex;" alt="{\displaystyle 0\leq i<n}" loading="lazy"></span>, the value <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle e_{i}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>i</mi>
</mrow>
</msub>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle e_{i}}</annotation>
</semantics>
</math></span><img src="./ebdc3a9cb1583d3204eff8918b558c293e0d2cf3.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.671ex; width:1.883ex; height:2.009ex;" alt="{\displaystyle e_{i}}" loading="lazy"></span> can be
retrieved quickly. This operation is called a
<b>lookup</b>. Furthermore, given the array <i>ar</i>, an index
<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 0\leq i<n}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mn>0</mn>
<mo>≤<!-- ≤ --></mo>
<mi>i</mi>
<mo>&lt;</mo>
<mi>n</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 0\leq i&lt;n}</annotation>
</semantics>
</math></span><img src="./3580bfd665087b84b88971bf567b87ab86b42871.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.505ex; width:9.557ex; height:2.343ex;" alt="{\displaystyle 0\leq i<n}" loading="lazy"></span> and a new value <i>v</i>, a new array <i>ar2</i> with
content <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle [e_{0},\dots ,e_{i-1},v,e_{i+1},\dots ,e_{n-1}]}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo stretchy="false">[</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>i</mi>
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msub>
<mo>,</mo>
<mi>v</mi>
<mo>,</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>i</mi>
<mo>+</mo>
<mn>1</mn>
</mrow>
</msub>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<msub>
<mi>e</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>n</mi>
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msub>
<mo stretchy="false">]</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle [e_{0},\dots ,e_{i-1},v,e_{i+1},\dots ,e_{n-1}]}</annotation>
</semantics>
</math></span><img src="./95adbea2fb090b6637b25148e5bf68c850c62427.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:29.353ex; height:2.843ex;" alt="{\displaystyle [e_{0},\dots ,e_{i-1},v,e_{i+1},\dots ,e_{n-1}]}" loading="lazy"></span> can
be created quickly. This operation is called an <b>update</b>. The
main difference between persistent and non-persistent arrays being
that, in non-persistent arrays, the array <i>ar</i> is destroyed during
the creation of <i>ar2</i>.
</p><p>For example, consider the following pseudocode.
</p>
<pre><i>array</i> = [0, 0, 0]
<i>updated_array</i> = <i>array</i>.update(0, 8)
<i>other_array</i> = <i>array</i>.update(1, 3)
<i>last_array</i> = <i>updated_array</i>.update(2, 5)
</pre>
<p>At the end of execution, the value of <i>array</i> is still [0, 0, 0], the
value of <i>updated_array</i> is [8, 0, 0], the value of <i>other_array</i>
is [0, 3, 0], and the value of <i>last_array</i> is [8, 0, 5].
</p><p>There exist two kinds of persistent arrays. A persistent array may be
either <b>partially</b> or <b>fully</b> persistent. A fully persistent
array may be updated an arbitrary number of times while a partially
persistent array may be updated at most once. In our previous example,
if <i>array</i> were only partially persistent, the creation of
<i>other_array</i> would be forbidden; however, the creation of
<i>last_array</i> would still be valid. Indeed, <i>updated_array</i> is an array
distinct from <i>array</i> and has never been updated before the creation
of <i>last_array</i>.
</p>
<div class="mw-heading mw-heading2"><h2 id="Lower_Bound_on_Persistent_Array_Lookup_Time">Lower Bound on Persistent Array Lookup Time</h2></div>
<p>Given that non-persistent arrays support both updates and lookups in constant time, it is natural to ask whether the same is possible with persistent arrays. The following theorem shows that under mild assumptions about the space complexity of the array, lookups must take <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \Omega (\log \log n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi mathvariant="normal">Ω<!-- Ω --></mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \Omega (\log \log n)}</annotation>
</semantics>
</math></span><img src="./abd3ed358ca0ff406e846ab34eacde0685b93373.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:11.6ex; height:2.843ex;" alt="{\displaystyle \Omega (\log \log n)}" loading="lazy"></span> time in the worst case, regardless of update time, in the <a href="Cell-probe_model" title="Cell-probe model">cell-probe model</a>.
</p>
<style data-mw-deduplicate="TemplateStyles:r1110004140">
/* start https://en.wikipedia.org/ */


.mw-parser-output .math_theorem{margin:1em 2em;padding:0.5em 1em 0.4em;border:1px solid #aaa;overflow:hidden}@media(max-width:500px){.mw-parser-output .math_theorem{margin:1em 0em;padding:0.5em 0.5em 0.4em}}


/* end https://en.wikipedia.org/ */
</style><div class="math_theorem" style="">
<p><strong class="theorem-name">Theorem<sup id="cite_ref-Straka_1-0" class="reference"><a href="#cite_note-Straka-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup class="reference nowrap"><span title="Page / location: 67–69">: 67–69 </span></sup></strong><span class="theoreme-tiret">—</span>Consider a partially persistent array with <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle n}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>n</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle n}</annotation>
</semantics>
</math></span><img src="./a601995d55609f2d9f5e233e36fbe9ea26011b3b.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.395ex; height:1.676ex;" alt="{\displaystyle n}" loading="lazy"></span> elements and <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle m=n^{\gamma }}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>m</mi>
<mo>=</mo>
<msup>
<mi>n</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>γ<!-- γ --></mi>
</mrow>
</msup>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle m=n^{\gamma }}</annotation>
</semantics>
</math></span><img src="./f0614a02a1cdc1c27136cf31e5ededbd246de82c.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:7.658ex; height:2.343ex;" alt="{\displaystyle m=n^{\gamma }}" loading="lazy"></span> modifications, where <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \gamma }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>γ<!-- γ --></mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \gamma }</annotation>
</semantics>
</math></span><img src="./a223c880b0ce3da8f64ee33c4f0010beee400b1a.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:1.262ex; height:2.176ex;" alt="{\displaystyle \gamma }" loading="lazy"></span> is a constant fulfilling <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 1<\gamma \leq 2}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mn>1</mn>
<mo>&lt;</mo>
<mi>γ<!-- γ --></mi>
<mo>≤<!-- ≤ --></mo>
<mn>2</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 1&lt;\gamma \leq 2}</annotation>
</semantics>
</math></span><img src="./985a6fb8352d5ae252140a0e60773635669a0b1c.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:9.784ex; height:2.676ex;" alt="{\displaystyle 1<\gamma \leq 2}" loading="lazy"></span>.
Assuming the space complexity of the array is <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(m\log ^{k}m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>m</mi>
<msup>
<mi>log</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>k</mi>
</mrow>
</msup>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(m\log ^{k}m)}</annotation>
</semantics>
</math></span><img src="./5bee4056573bcd8bd139e8f1b0743b61c2359e42.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.498ex; height:3.176ex;" alt="{\displaystyle O(m\log ^{k}m)}" loading="lazy"></span> for a constant <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle k}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>k</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle k}</annotation>
</semantics>
</math></span><img src="./c3c9a2c7b599b37105512c5d570edc034056dd40.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.211ex; height:2.176ex;" alt="{\displaystyle k}" loading="lazy"></span>,
the lower bound on the lookup complexity in this partially persistent
array is <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \Omega (\log \log n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi mathvariant="normal">Ω<!-- Ω --></mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \Omega (\log \log n)}</annotation>
</semantics>
</math></span><img src="./abd3ed358ca0ff406e846ab34eacde0685b93373.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:11.6ex; height:2.843ex;" alt="{\displaystyle \Omega (\log \log n)}" loading="lazy"></span>.
</p>
</div>
<div class="mw-heading mw-heading2"><h2 id="Implementations">Implementations</h2></div>
<p>In this section, <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle n}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>n</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle n}</annotation>
</semantics>
</math></span><img src="./a601995d55609f2d9f5e233e36fbe9ea26011b3b.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.395ex; height:1.676ex;" alt="{\displaystyle n}" loading="lazy"></span> is the number of elements of the array, and <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle m}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>m</mi>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle m}</annotation>
</semantics>
</math></span><img src="./0a07d98bb302f3856cbabc47b2b9016692e3f7bc.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:2.04ex; height:1.676ex;" alt="{\displaystyle m}" loading="lazy"></span> is the number of updates.
</p>
<div class="mw-heading mw-heading3"><h3 id="Worst_case_log-time">Worst case log-time</h3></div>
<p>The most straightforward implementation of a fully persistent array uses an arbitrary persistent map, whose keys are the numbers from <i>0</i> to <i>n</i> − 1. A persistent map may be implemented using a persistent <a href="Balanced_tree" class="mw-redirect" title="Balanced tree">balanced tree</a>, in which case both updates and lookups would take <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(\log n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(\log n)}</annotation>
</semantics>
</math></span><img src="./aae0f22048ba6b7c05dbae17b056bfa16e21807d.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:8.336ex; height:2.843ex;" alt="{\displaystyle O(\log n)}" loading="lazy"></span> time. This implementation is optimal for the <a href="Pointer_machine" title="Pointer machine">pointer machine</a> model.<sup id="cite_ref-Straka_1-1" class="reference"><a href="#cite_note-Straka-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup class="reference nowrap"><span title="Page / location: 88–89">: 88–89 </span></sup>
</p>
<div class="mw-heading mw-heading3"><h3 id="Shallow_binding">Shallow binding</h3></div>
<p>A fully persistent array may be implemented using an array and the
so-called Baker's trick.<sup id="cite_ref-ML_2-0" class="reference"><a href="#cite_note-ML-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup> This implementation is used in the <a href="OCaml" title="OCaml">OCaml</a> module parray.ml<sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup> by Jean-Christophe Filliâtre.
</p><p>In order to define this implementation, a few other definitions must
be given. An <b>initial array</b> is an array that is not generated by
an update on another array. A <b>child</b> of an array <i>ar</i> is an
array of the form <i>ar.update(i,v)</i>, and <i>ar</i> is the <b>parent</b>
of <i>ar.update(i,v)</i>. A <b>descendant</b> of an array <i>ar</i> is either
<i>ar</i> or the descendant of a child of <i>ar</i>. The <b>initial array</b>
of an array <i>ar</i> is either <i>ar</i> if <i>ar</i> is initial, or it is the
initial array of the parent of <i>ar</i>. That is, the initial array of
<i>ar</i> is the unique array <i>init</i> such that <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathrm {ar} =init.update(i_{0},v_{0}).\dots .update(i_{m},v_{m})}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="normal">a</mi>
<mi mathvariant="normal">r</mi>
</mrow>
<mo>=</mo>
<mi>i</mi>
<mi>n</mi>
<mi>i</mi>
<mi>t</mi>
<mo>.</mo>
<mi>u</mi>
<mi>p</mi>
<mi>d</mi>
<mi>a</mi>
<mi>t</mi>
<mi>e</mi>
<mo stretchy="false">(</mo>
<msub>
<mi>i</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo>,</mo>
<msub>
<mi>v</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo stretchy="false">)</mo>
<mo>.</mo>
<mo>…<!-- … --></mo>
<mo>.</mo>
<mi>u</mi>
<mi>p</mi>
<mi>d</mi>
<mi>a</mi>
<mi>t</mi>
<mi>e</mi>
<mo stretchy="false">(</mo>
<msub>
<mi>i</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>m</mi>
</mrow>
</msub>
<mo>,</mo>
<msub>
<mi>v</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>m</mi>
</mrow>
</msub>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathrm {ar} =init.update(i_{0},v_{0}).\dots .update(i_{m},v_{m})}</annotation>
</semantics>
</math></span><img src="./2a2a900175d2b791e01cd12b248732b8c4e2ca5f.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:43.965ex; height:2.843ex;" alt="{\displaystyle \mathrm {ar} =init.update(i_{0},v_{0}).\dots .update(i_{m},v_{m})}" loading="lazy"></span>, with <i>init</i> initial
and <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle i_{0},\dots ,i_{m}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>i</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<msub>
<mi>i</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>m</mi>
</mrow>
</msub>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle i_{0},\dots ,i_{m}}</annotation>
</semantics>
</math></span><img src="./aef8cc15c80afc053851505c44765e77bd3ddee1.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.671ex; width:9.512ex; height:2.509ex;" alt="{\displaystyle i_{0},\dots ,i_{m}}" loading="lazy"></span> an arbitrary sequence of indexes and
<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle v_{0},\dots ,v_{m}}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msub>
<mi>v</mi>
<mrow class="MJX-TeXAtom-ORD">
<mn>0</mn>
</mrow>
</msub>
<mo>,</mo>
<mo>…<!-- … --></mo>
<mo>,</mo>
<msub>
<mi>v</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>m</mi>
</mrow>
</msub>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle v_{0},\dots ,v_{m}}</annotation>
</semantics>
</math></span><img src="./63973dac99ac1bc4fe0b24b5b028b9d16acd1d96.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.671ex; width:10.163ex; height:2.009ex;" alt="{\displaystyle v_{0},\dots ,v_{m}}" loading="lazy"></span> an arbitrary sequence of value. A
<i>family</i> of arrays is thus a set of arrays containing an initial
array and all of its descendants. Finally, the tree of a family of
arrays is the <a href="Tree_(data_structure)" class="mw-redirect" title="Tree (data structure)">tree</a> whose nodes are the
arrays, and with an edge <i>e</i> from <i>ar</i> to each of its children
<i>ar.update(i,v)</i>.
</p><p>A persistent array using Baker's trick consists of a pair with
an actual array called <i>array</i> and the tree of arrays. This tree
admits an arbitrary root - not necessarily the initial array. The
root may be moved to an arbitrary node of the tree. Changing the root
from <i>root</i> to an arbitrary node <i>ar</i> takes time proportional to
the depth of <i>ar</i>. That is, in the distance between <i>root</i> and
<i>ar</i>. Similarly, looking up a value takes time proportional to the
distance between the array and the root of its family. Thus, if the
same array <i>ar</i> may be lookup multiple times, it is more efficient
to move the root to <i>ar</i> before doing the lookup. Finally updating
an array only takes <a href="Constant_time" class="mw-redirect" title="Constant time">constant time</a>.
</p><p>Technically, given two adjacent arrays <i>ar1</i> and <i>ar2</i>, with
<i>ar1</i> closer to the root than <i>ar2</i>, the edge from <i>ar1</i> to
<i>ar2</i> is labelled by <i>(i,ar2[i])</i>, where <i>i</i> the only position
whose value differ between <i>ar1</i> and <i>ar2</i>.
</p><p>Accessing an element <i>i</i> of an array <i>ar</i> is done as follows. If
<i>ar</i> is the root, then <i>ar[i]</i> equals <i>root[i]</i>. Otherwise, let
<i>e</i> the edge leaving <i>ar</i> toward the root. If the label of <i>e</i>
is <i>(i,v)</i> then <i>ar[i]</i> equals <i>v</i>. Otherwise, let <i>ar2</i> be
the other node of the edge <i>e</i>. Then <i>ar[i]</i> equals
<i>ar2[i]</i>. The computation of <i>ar2[i]</i> is done recursively using
the same definition.
</p><p>The creation of <i>ar.update(i,v)</i> consists in adding a new node
<i>ar2</i> to the tree, and an edge <i>e</i> from <i>ar</i> to <i>ar2</i> labelled
by <i>(i,v)</i>.
</p><p>Finally, moving the root to a node <i>ar</i> is done as follows. If
<i>ar</i> is already the root, there is nothing to do. Otherwise, let
<i>e</i> the edge leaving <i>ar</i> toward the current root, <i>(i,v)</i> its
label and <i>ar2</i> the other end of <i>e</i>. Moving the root to <i>ar</i> is
done by first moving the root to <i>ar2</i>, changing the label of <i>e</i>
to <i>(i, ar2[i])</i>, and changing <i>array[i]</i> to <i>v</i>.
</p><p>Updates take <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(1)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mn>1</mn>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(1)}</annotation>
</semantics>
</math></span><img src="./e66384bc40452c5452f33563fe0e27e803b0cc21.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:4.745ex; height:2.843ex;" alt="{\displaystyle O(1)}" loading="lazy"></span> time. Lookups take <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(1)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mn>1</mn>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(1)}</annotation>
</semantics>
</math></span><img src="./e66384bc40452c5452f33563fe0e27e803b0cc21.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:4.745ex; height:2.843ex;" alt="{\displaystyle O(1)}" loading="lazy"></span> time if the root is the array being looked up, but <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \Theta (m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi mathvariant="normal">Θ<!-- Θ --></mi>
<mo stretchy="false">(</mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \Theta (m)}</annotation>
</semantics>
</math></span><img src="./80a5cb7e7794c6e0c32bbed3e25c64f1c22a1a57.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:5.658ex; height:2.843ex;" alt="{\displaystyle \Theta (m)}" loading="lazy"></span> time in the worst case.
</p>
<div class="mw-heading mw-heading3"><h3 id="Expected_amortized_log-log-time">Expected amortized log-log-time</h3></div>
<p>In 1989, Dietz<sup id="cite_ref-Dietz_4-0" class="reference"><a href="#cite_note-Dietz-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup>
gave an implementation of fully persistent arrays using <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(m+n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>m</mi>
<mo>+</mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(m+n)}</annotation>
</semantics>
</math></span><img src="./0922aa919079469e54e4c3affe9b7ab456f1a124.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:9.858ex; height:2.843ex;" alt="{\displaystyle O(m+n)}" loading="lazy"></span> space such that lookups can be done in <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(\log \log m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(\log \log m)}</annotation>
</semantics>
</math></span><img src="./541113a51c1eaff2598b6e7d8044360d64391ffe.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.341ex; height:2.843ex;" alt="{\displaystyle O(\log \log m)}" loading="lazy"></span> worst-case time, and updates can be done in
<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(\log \log m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(\log \log m)}</annotation>
</semantics>
</math></span><img src="./541113a51c1eaff2598b6e7d8044360d64391ffe.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.341ex; height:2.843ex;" alt="{\displaystyle O(\log \log m)}" loading="lazy"></span> expected amortized time. By the lower bound from the previous section, this time complexity for lookup is optimal when <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle m=n^{\gamma }}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>m</mi>
<mo>=</mo>
<msup>
<mi>n</mi>
<mrow class="MJX-TeXAtom-ORD">
<mi>γ<!-- γ --></mi>
</mrow>
</msup>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle m=n^{\gamma }}</annotation>
</semantics>
</math></span><img src="./f0614a02a1cdc1c27136cf31e5ededbd246de82c.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:7.658ex; height:2.343ex;" alt="{\displaystyle m=n^{\gamma }}" loading="lazy"></span> for <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \gamma \in (1,2]}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>γ<!-- γ --></mi>
<mo>∈<!-- ∈ --></mo>
<mo stretchy="false">(</mo>
<mn>1</mn>
<mo>,</mo>
<mn>2</mn>
<mo stretchy="false">]</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \gamma \in (1,2]}</annotation>
</semantics>
</math></span><img src="./e5ea13cdfbf327c0dcbd99c790aa74091c4e0d54.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:9.013ex; height:2.843ex;" alt="{\displaystyle \gamma \in (1,2]}" loading="lazy"></span>. This implementation is related to the <a href="Order-maintenance_problem" title="Order-maintenance problem">order-maintenance problem</a> and involves <a href="VEB_tree" class="mw-redirect" title="VEB tree">vEB trees</a>, one for the entire array and one for each index.
</p><p>Straka showed that the times for both operations can be (slightly) improved to <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(\log \log \min(m,n))}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mo movablelimits="true" form="prefix">min</mo>
<mo stretchy="false">(</mo>
<mi>m</mi>
<mo>,</mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(\log \log \min(m,n))}</annotation>
</semantics>
</math></span><img src="./a452b0b42b748c0fc94557dfd5b3ccabf3c74a0a.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:20.454ex; height:2.843ex;" alt="{\displaystyle O(\log \log \min(m,n))}" loading="lazy"></span>.<sup id="cite_ref-Straka_1-2" class="reference"><a href="#cite_note-Straka-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup class="reference nowrap"><span title="Page / location: 88–89">: 88–89 </span></sup>
</p>
<div class="mw-heading mw-heading3"><h3 id="Worst_case_log-log-time">Worst case log-log-time</h3></div>
<p>Straka showed how to achieve <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O((\log \log m)^{2}/\log \log \log m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msup>
<mrow class="MJX-TeXAtom-ORD">
<mo>/</mo>
</mrow>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O((\log \log m)^{2}/\log \log \log m)}</annotation>
</semantics>
</math></span><img src="./464e516e309e9d98b0302a040c65f65cd03e3e94.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:28.871ex; height:3.176ex;" alt="{\displaystyle O((\log \log m)^{2}/\log \log \log m)}" loading="lazy"></span> worst-case time and linear (<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(m+n)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>m</mi>
<mo>+</mo>
<mi>n</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(m+n)}</annotation>
</semantics>
</math></span><img src="./0922aa919079469e54e4c3affe9b7ab456f1a124.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:9.858ex; height:2.843ex;" alt="{\displaystyle O(m+n)}" loading="lazy"></span>) space, or <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(\log \log m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(\log \log m)}</annotation>
</semantics>
</math></span><img src="./541113a51c1eaff2598b6e7d8044360d64391ffe.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.341ex; height:2.843ex;" alt="{\displaystyle O(\log \log m)}" loading="lazy"></span> worst-case time and super-linear space. It remains open whether it is possible to achieve worst-case time <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle O(\log \log m)}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mi>O</mi>
<mo stretchy="false">(</mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>log</mi>
<mo>⁡<!-- ⁡ --></mo>
<mi>m</mi>
<mo stretchy="false">)</mo>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle O(\log \log m)}</annotation>
</semantics>
</math></span><img src="./541113a51c1eaff2598b6e7d8044360d64391ffe.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:12.341ex; height:2.843ex;" alt="{\displaystyle O(\log \log m)}" loading="lazy"></span> subject to linear space.<sup id="cite_ref-Straka_1-3" class="reference"><a href="#cite_note-Straka-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup><sup class="reference nowrap"><span title="Page / location: 88">: 88 </span></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */


.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}


/* end https://en.wikipedia.org/ */
</style><div class="reflist">
<div class="mw-references-wrap"><ol class="references">
<li id="cite_note-Straka-1"><span class="mw-cite-backlink">^ <a href="#cite_ref-Straka_1-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-Straka_1-1"><sup><i><b>b</b></i></sup></a> <a href="#cite_ref-Straka_1-2"><sup><i><b>c</b></i></sup></a> <a href="#cite_ref-Straka_1-3"><sup><i><b>d</b></i></sup></a></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */


.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}


/* end https://en.wikipedia.org/ */
</style><cite id="CITEREFStraka_e2013" class="citation book cs1">Straka e, Milan (2013). <i>Functional Data Structures and Algorithms</i>. Prague.</cite><span class="cs1-maint citation-comment"><code class="cs1-code">{{cite book}}</code>: CS1 maint: location missing publisher (link)</span></span>
</li>
<li id="cite_note-ML-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-ML_2-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFFillâtreConchon2007" class="citation book cs1">Fillâtre, Jean-Christophe; Conchon, Sylvain (2007). <a rel="nofollow" class="external text" href="https://www.lri.fr/~filliatr/ftp/publis/puf-wml07.pdf"><i>A Persistent Union-find Data Structure</i></a> <span class="cs1-format">(PDF)</span>. New York, NY, USA: ACM. pp.&nbsp;<span class="nowrap">37–</span>46. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a>&nbsp;<bdi>978-1-59593-676-9</bdi>.</cite></span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-3">^</a></b></span> <span class="reference-text"><cite id="CITEREFFilliâtre" class="citation web cs1">Filliâtre, Jean-Christophe. <a rel="nofollow" class="external text" href="https://github.com/backtracking/ocaml-bazaar/blob/main/parray.ml">"Persistent-array implementation"</a>. <i><a href="GitHub" title="GitHub">GitHub</a></i>.</cite></span>
</li>
<li id="cite_note-Dietz-4"><span class="mw-cite-backlink"><b><a href="#cite_ref-Dietz_4-0">^</a></b></span> <span class="reference-text"><cite id="CITEREFDietz1989" class="citation conference cs1">Dietz, Paul F. (1989). "Fully persistent arrays". <i>Proceedings of the Algorithms and Data Structures</i>. pp.&nbsp;<span class="nowrap">67–</span>74. <a href="CiteSeerX_(identifier)" class="mw-redirect" title="CiteSeerX (identifier)">CiteSeerX</a>&nbsp;<span class="id-lock-free" title="Freely accessible"><a rel="nofollow" class="external text" href="https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.621.1599">10.1.1.621.1599</a></span>. <a href="Doi_(identifier)" class="mw-redirect" title="Doi (identifier)">doi</a>:<a rel="nofollow" class="external text" href="https://doi.org/10.1007%2F3-540-51542-9_8">10.1007/3-540-51542-9_8</a>.</cite></span>
</li>
</ol></div></div><p>.</p></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-08-05" href="https://en.wikipedia.org/wiki/?title=Persistent_array&amp;oldid=1304333723">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>

</body></html>